[client-v2] Fixed converting integers thru decimal#2814
[client-v2] Fixed converting integers thru decimal#2814
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes loss of precision when converting integer values to BigDecimal in the client-v2 binary reader path (addressing #2748), ensuring large Int64/UInt64/... values are not truncated during conversion.
Changes:
- Update numeric-to-
BigDecimalconversion to avoiddouble-based conversion for integer types (use integral/string-based conversion instead). - Align serialization helpers to use
NumberConverterforBigInteger/BigDecimalconversions in a few numeric cases. - Add a focused unit test covering
getBigDecimal()for integer widths from 8 to 256 bits (signed/unsigned).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| client-v2/src/test/java/com/clickhouse/client/api/data_formats/ClickHouseBinaryFormatReaderTest.java | Adds regression test ensuring integer types (Int8..Int256/UInt8..UInt256) convert to BigDecimal without truncation. |
| client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/ValueConverters.java | Fixes Number -> BigDecimal conversion to preserve integer precision. |
| client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/SerializerUtils.java | Routes decimal and big-int serialization through NumberConverter for consistency. |
| client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/NumberConverter.java | Fixes toBigDecimal() to preserve precision for integer Number types (no double truncation). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/SerializerUtils.java
Outdated
Show resolved
Hide resolved
Client V2 CoverageCoverage Report
Class Coverage
|
client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/SerializerUtils.java
Show resolved
Hide resolved
| String sql = "SELECT toInt64(" + Long.MAX_VALUE + ") AS i64, " | ||
| + "toUInt64('" + expectedUInt64.toPlainString() + "') AS u64"; | ||
|
|
||
| try (QueryResponse response = client.query(sql).get(3, TimeUnit.SECONDS)) { |
There was a problem hiding this comment.
This integration test uses a hard-coded 3-second timeout on client.query(sql).get(...), while the rest of DataTypeTests generally uses .get() without a short timeout. A small timeout can make CI runs flaky on slower environments. Consider aligning with the existing pattern (no timeout) or using a shared/longer timeout constant for integration tests in this class.
| try (QueryResponse response = client.query(sql).get(3, TimeUnit.SECONDS)) { | |
| try (QueryResponse response = client.query(sql).get()) { |
|
JDBC V2 CoverageCoverage Report
Class Coverage
|
JDBC V1 CoverageCoverage Report
Class Coverage
|
Client V1 CoverageCoverage Report
Class Coverage
|
mzitnik
left a comment
There was a problem hiding this comment.
Looks like we have partial coverage from tests coverage from new code is less than 80%
Another qestions currently we are running for integration prespective should we also tests it from JDBC prepective (should also support implicit conversions)
mzitnik
left a comment
There was a problem hiding this comment.
Lets try to extend our coverage test
|
|
||
| public BigDecimal convertNumberToBigDecimal(Object value) { | ||
| return BigDecimal.valueOf(((Number) value).doubleValue()); | ||
| Number number = (Number) value; |
There was a problem hiding this comment.
missing checks
- value not null
- instanceof Number before cast
| BigInteger.valueOf(120), | ||
| BigInteger.valueOf(120), | ||
| BigInteger.valueOf(120), | ||
| 120.0f, |
There was a problem hiding this comment.
I think if we set it to 0.1f, we can lose precision, lets add different values to test the conversion logic


Summary
Closes #2748
Checklist
Delete items not relevant to your PR: